#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <SFML/Graphics.hpp>

#include <unistd.h>

using namespace sf;

// 定义方向枚举
enum Direction {
    UP,
    DOWN,
    LEFT,
    RIGHT
};

// 定义蛇的身体部分结构体
struct Point {
    int x;
    int y;
    // 添加默认构造函数
    Point() : x(0), y(0) {}
    // 添加构造函数
    Point(int x, int y) : x(x), y(y) {}
  };

// 全局变量
const int WIDTH = 20;
const int HEIGHT = 20;
const int BLOCK_SIZE = 20;
std::vector<Point> snake;
Point food;
Direction dir;
bool gameOver;
int score;

// 初始化游戏
void Setup() {
    gameOver = false;
    dir = RIGHT;
    snake.clear();
    snake.push_back(Point(WIDTH / 2, HEIGHT / 2));
    srand(time(NULL));
    // 修正 food 初始化问题，使用构造函数
    food = Point(rand() % WIDTH, rand() % HEIGHT);
    score = 0;
}

// 绘制游戏界面
void Draw(sf::RenderWindow& window) {
    window.clear();
    // 绘制蛇
    for (const auto& p : snake) {
        sf::RectangleShape block(sf::Vector2f(BLOCK_SIZE, BLOCK_SIZE));
        // 修改 setPosition 调用
        block.setPosition(sf::Vector2f(p.x * BLOCK_SIZE, p.y * BLOCK_SIZE));
        block.setFillColor(sf::Color::Green);
        window.draw(block);
    }
    // 绘制食物
    sf::RectangleShape foodBlock(sf::Vector2f(BLOCK_SIZE, BLOCK_SIZE));
    // 修改 setPosition 调用
    foodBlock.setPosition(sf::Vector2f(food.x * BLOCK_SIZE, food.y * BLOCK_SIZE));
    foodBlock.setFillColor(sf::Color::Red);
    window.draw(foodBlock);
    // 显示分数
    sf::Font font;
    // 修改为 openFromFile
    if (font.openFromFile("arial.ttf")) {
        // 修改 Text 构造函数
        sf::Text scoreText("Score: " + std::to_string(score), font, 24);
        scoreText.setFillColor(sf::Color::White);
        window.draw(scoreText);
    }
    window.display();
}

// 处理输入
// 修改 Input 函数以移除对 conio.h 的依赖
void Input() {
    // 修改键盘按键枚举
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W)) {
        if (dir != DOWN) dir = UP;
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::S)) {
        if (dir != UP) dir = DOWN;
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A)) {
        if (dir != RIGHT) dir = LEFT;
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D)) {
        if (dir != LEFT) dir = RIGHT;
    }
    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::X)) {
        gameOver = true;
    }
}

// 游戏逻辑
void Logic() {
    Point head = snake[0];
    switch (dir) {
        case UP:
            head.y--;
            break;
        case DOWN:
            head.y++;
            break;
        case LEFT:
            head.x--;
            break;
        case RIGHT:
            head.x++;
            break;
    }

    // 检查是否吃到食物
    if (head.x == food.x && head.y == food.y) {
        score += 10;
        food = Point(rand() % WIDTH, rand() % HEIGHT);
    } else {
        snake.pop_back();
    }

    // 检查是否撞到边界或自己
    if (head.x < 0 || head.x >= WIDTH || head.y < 0 || head.y >= HEIGHT) {
        gameOver = true;
    }
    for (size_t i = 1; i < snake.size(); i++) {
        if (head.x == snake[i].x && head.y == snake[i].y) {
            gameOver = true;
        }
    }

    snake.insert(snake.begin(), head);
}

int main() {
    Setup();
    // 修改 VideoMode 构造函数
    sf::RenderWindow window(sf::VideoMode(sf::Vector2u(WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE)), "Snake Game");
    while (window.isOpen()) {
        // 处理 SFML 事件
        std::optional<sf::Event> event = window.pollEvent();
        if (event.has_value()) {
            if (event->type == sf::Event::Closed)
                window.close();
        }
        Input();
        Logic();
        Draw(window);
        usleep(100000);
    }
    std::cout << "Game Over!" << std::endl;
    return 0;
}